#include <glog/logging.h>
#include <glog/log_severity.h>

#include "incoming_handle.h"
#include "parser.h"
#include "assemble.h"
#include "client_map.h"
#include "kcp_agent.h"


IncomingHandler::IncomingHandler(int type) : MessageDeliver(type)
{

}

IncomingHandler::~IncomingHandler()
{

}

int IncomingHandler::Execute(void *args)
{
	SignalCmd *qos_cmd = reinterpret_cast<SignalCmd *>(args);
	
	//int sub_type = qos_cmd->ExtType();

	HandleMsg(qos_cmd);

	return 0;
}

int IncomingHandler::HandleMsg(SignalCmd *msg)
{
	LOG(INFO)<<"IncomingHandler::HandleMsg, msg: "<<(char *)msg->payload_;

	std::string content;
	std::string peer_id;
	std::string id;
	int type = 0;

	event_type_e event = Parser::ParseEvent((const char *)msg->payload_, id, peer_id, type, content);

	LOG(INFO)<<"IncomingHandler::HandleMsg, id: "<<id<<" content: "<<content<<" peer_id:"<<peer_id;

	switch (event)
	{
		case EVENT_TYPE_HEART_BEAT:
			HandleHB(id, type, msg->priv_);
			break;
		case EVENT_TYPE_CONN_REQ:
			HandleConnReq(id, peer_id, content, msg->priv_);
			break;
		case EVENT_TYPE_CONN_RESP:
			HandleConnResp(id, peer_id, content, msg->priv_);
			break;	
		case EVENT_TYPE_QUERY_DEVICE:
			HandleQueryDevice(id, msg->priv_);
			break;	
		default:
			break;
	}

	return 0;
}

void IncomingHandler::HandleHB(std::string &id, int type, void *data)
{
	ClientInfo client;
	client.client_ = data;
	client.type_ = type;

	ClientMap::Instance()->Push(id, client);
}

void IncomingHandler::HandleConnReq(std::string &id, std::string &peer_id, std::string &ice_info, void *data)
{
	HandleHB(id, 1, data);
	ClientMap::Instance()->UpdateICE(id, ice_info);

	ClientInfo client;
	int ret = ClientMap::Instance()->GetAgent(peer_id, client);
	if (ret != -1)
	{
		KcpAgent *kcp_agent = reinterpret_cast<KcpAgent *>(client.client_);

		std::string json_str;

		Assembler::AssembleReqConnMsg(ice_info, id, json_str);

		kcp_agent->Send(json_str);
	}
}

void IncomingHandler::HandleConnResp(std::string &id, std::string &peer_id, std::string &ice_info, void *data)
{
	HandleHB(id, 0, data);
	ClientMap::Instance()->UpdateICE(id, ice_info);

	ClientInfo client;
	int ret = ClientMap::Instance()->GetAgent(peer_id, client);
	if (ret != -1)
	{
		KcpAgent *kcp_agent = reinterpret_cast<KcpAgent *>(client.client_);

		std::string json_str;

		Assembler::AssembleRespConnMsg(ice_info, json_str);

		kcp_agent->Send(json_str);
	}
}

void IncomingHandler::HandleQueryDevice(std::string &id, void *data)
{
	HandleHB(id, 1, data);

	KcpAgent *kcp_agent = reinterpret_cast<KcpAgent *>(data);

	std::string json_str;

	ID_LIST id_list;
	ClientMap::Instance()->GetIDList(id_list);

	Assembler::AssembleListDevMsg(id_list, json_str);

	kcp_agent->Send(json_str);
}


